package org.zjx.data;

import org.zjx.command.entity.screen.*;
import org.zjx.command.enums.TeleportType;

import java.awt.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public abstract class BaseSceneBuilder {
    protected Scene scene;
    protected List<Teleport> teleports = new ArrayList<>();
    protected List<Room> rooms = new ArrayList<>();
    protected List<String> monsters = new ArrayList<>();

    /**
     * 抽象方法：子类必须实现，返回场景名称和尺寸
     */
    protected abstract String getSceneName();
    protected abstract Dimension getSceneSize();

    /**
     * 模板方法：定义构建流程
     */
    public Scene build() {
        // 1. 创建基础场景
        createBaseScene();

        // 2. 添加NPC（由子类实现）
        addNpcs();

        // 3. 添加房间（由子类实现）
        addRooms();

        // 4. 添加传送点（由子类实现）
        addTeleports();

        // 5. 应用所有配置
        applyConfigurations();

        return scene;
    }

    /**
     * 创建基础场景
     */
    protected void createBaseScene() {
        Dimension size = getSceneSize();
        scene = new Scene(getSceneName(), new TabMap(size.width, size.height));
    }

    /**
     * 是否需要摄妖香
     */
    public boolean repellingIncense(){
        return !monsters.isEmpty();
    }

    /**
     * 添加暗怪（子类实现）
     */
    protected abstract void addMonsters();

    /**
     * 添加NPC（子类实现）
     */
    protected abstract void addNpcs();

    /**
     * 添加房间（子类实现）
     */
    protected abstract void addRooms();

    /**
     * 添加传送点（子类实现）
     */
    protected abstract void addTeleports();

    /**
     * 应用所有配置到场景
     */
    protected void applyConfigurations() {
        // 添加房间到场景
        for (Room room : rooms) {
            scene.addRoom(room);
        }

        // 添加传送点到场景
        for (Teleport teleport : teleports) {
            scene.addTeleport(teleport);
        }
    }

    // ========== 便捷方法 ==========

    /**
     * 添加带功能的NPC到场景
     */
    protected void addNpc(String name, Point[] points, Map<String, List<String>> functions) {
        Npc npc = new Npc(scene.getName(),name);
        for (Point point : points) {
            npc.addMovePath(point);
        }
        if (functions != null) {
            npc.functions.putAll(functions);
        }
        scene.addNpc(npc);
    }

    /**
     * 添加带功能的NPC到房间
     */
    protected void addNpcToRoom(Room room, String name, Point[] points, Map<String, List<String>> functions) {
        Npc npc = new Npc(room.getName(),name);
        for (Point point : points) {
            npc.addMovePath(point);
        }
        if (functions != null) {
            npc.functions.putAll(functions);
        }
        room.addNpc(npc);
    }

    /**
     * 添加NPC到场景
     */
    protected void addNpc(String name, Point... points) {
        Npc npc = new Npc(scene.getName(),name);
        for (Point point : points) {
            npc.addMovePath(point);
        }
        scene.addNpc(npc);
    }

    /**
     * 添加NPC到房间
     */
    protected void addNpcToRoom(Room room, String name, Point... points) {
        Npc npc = new Npc(room.getName(),name);
        for (Point point : points) {
            npc.addMovePath(point);
        }
        room.addNpc(npc);
    }

    /**
     * 创建房间
     */
    protected Room createRoom(String name, Dimension size) {
        TabMap tabMap = size != null ? new TabMap(size.width, size.height) : null;
        return new Room(name, tabMap);
    }

    /**
     * 添加场景传送点
     */
    protected void addSceneTeleport(Point fromPoint, String toScene, Point toPoint, Point clickPoint) {
        Teleport teleport = new Teleport(
                scene.getName(), fromPoint, toScene, toPoint,
                clickPoint, null, TeleportType.SCENE_TRANSFER
        );
        teleports.add(teleport);
    }

    /**
     * 添加NPC传送点
     */
    protected void addNpcTeleport(String npcName, Point npcPoint, String toScene, Point toPoint, Point clickPoint) {
        Npc npc = new Npc(scene.getName(),npcName).addMovePath(npcPoint);
        Teleport teleport = new Teleport(
                scene.getName(), npcPoint, toScene, toPoint,
                clickPoint, npc, TeleportType.NPC_TRANSFER
        );
        teleports.add(teleport);
    }

    /**
     * 添加房间入口传送点
     */
    protected void addRoomTeleport(Point fromPoint, String toRoom, Point toPoint, Point clickPoint) {
        Teleport teleport = new Teleport(
                scene.getName(), fromPoint, toRoom, toPoint,
                clickPoint, null, TeleportType.ROOM_ENTER
        );
        teleports.add(teleport);
    }

    /**
     * 生成JSON文件
     */
    public void generateJsonFile(String filePath) throws IOException {
        Scene scene = build();
        String json = SceneJsonSerializer.sceneToJson(scene);
        Files.write(Paths.get(filePath), json.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 主方法模板
     */
    public void execute(String fileName, String sceneName) {
        try {
            generateJsonFile(fileName);
            System.out.println(sceneName + "场景JSON文件生成成功！");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}